package socket;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class Client {

    private JFrame frame;
    private JTextField inputField;
    private JTextArea chatArea;
    private Socket socket;
    private BufferedWriter writer;
    private BufferedReader reader;

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            try {
                Client window = new Client();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    public Client() {
        initialize();
        connectToServer();
    }

    private void initialize() {
        frame = new JFrame("简易聊天室客户端");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(450, 300);
        frame.setLayout(new BorderLayout());

        chatArea = new JTextArea();
        chatArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(chatArea);
        frame.add(scrollPane, BorderLayout.CENTER);

        JPanel inputPanel = new JPanel();
        inputPanel.setLayout(new BorderLayout());

        inputField = new JTextField();
        inputField.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                sendMessage(inputField.getText());
                inputField.setText("");
            }
        });
        inputPanel.add(inputField, BorderLayout.CENTER);

        JButton sendButton = new JButton("发送");
        sendButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                sendMessage(inputField.getText());
                inputField.setText("");
            }
        });
        inputPanel.add(sendButton, BorderLayout.EAST);

        frame.add(inputPanel, BorderLayout.SOUTH);
    }

    private void connectToServer() {
        try {
            System.out.println("正在连接服务端……");
            socket = new Socket("127.0.0.1", 8089);
            System.out.println("连接服务端成功！！！");
            writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));

            // 新建一个线程来持续监听服务器的消息
            Thread messageListener = new Thread(new MessageListener());
            messageListener.start();
        } catch (IOException e) {
            JOptionPane.showMessageDialog(frame, "连接服务器失败：" + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
            System.exit(1);
        }
    }

    private void sendMessage(String message) {
        if (message.trim().isEmpty()) return;
        try {
            writer.write(message + "\n");
            writer.flush();
            chatArea.append("我: " + message + "\n");
        } catch (IOException e) {
            JOptionPane.showMessageDialog(frame, "发送消息失败：" + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            disconnect();
        }
    }

    private class MessageListener implements Runnable {
        @Override
        public void run() {
            String message;
            try {
                while ((message = reader.readLine()) != null) {
                    String finalMessage = message;
                    SwingUtilities.invokeLater(() -> chatArea.append(finalMessage + "\n"));
                }
            } catch (IOException e) {
                JOptionPane.showMessageDialog(frame, "接收消息时发生错误：" + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            } finally {
                disconnect();
            }
        }
    }

    private void disconnect() {
        try {
            if (reader != null) reader.close();
            if (writer != null) writer.close();
            if (socket != null) socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.exit(0);
    }
}